iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0
Modern Web

擁抱 .Net Core系列 第 23

[Day23] 路由 Routing - 2

  • 分享至 

  • xImage
  •  

Endpoint

前一天解述了路由的組成,今天來談談端點Endpoint

Endpoint可以視為由RequestDelegate(middleware那個)跟Metadata集合所組成的類型

Endpoint.cs

public class Endpoint
{
public Endpoint(
    RequestDelegate? requestDelegate,
    EndpointMetadataCollection? metadata,
    string? displayName)
{
    // All are allowed to be null
    RequestDelegate = requestDelegate;
    Metadata = metadata ?? EndpointMetadataCollection.Empty;
    DisplayName = displayName;
}
public string? DisplayName { get; }
public EndpointMetadataCollection Metadata { get; }
public RequestDelegate? RequestDelegate { get; }
}

EndpointMetadataCollection 本質上是一個IReadOnlyList<object>
也就是說,任何物件都可以被視為端點的MetaData
包含CorsMetadata, AuthorizeData等等

做為一個Routing 中的Endpoint
最後會用物件RouteEndpoint來表示
RouteEndpoint.cs

public sealed class RouteEndpoint : Endpoint
{
    public RouteEndpoint(
        RequestDelegate requestDelegate,
        RoutePattern routePattern,
        int order,
        EndpointMetadataCollection? metadata,
        string? displayName)
        : base(requestDelegate, metadata, displayName)
    {
        if (requestDelegate == null)
        {
            throw new ArgumentNullException(nameof(requestDelegate));
        }

        if (routePattern == null)
        {
            throw new ArgumentNullException(nameof(routePattern));
        }

        RoutePattern = routePattern;
        Order = order;
    }
    public int Order { get; }
    public RoutePattern RoutePattern { get; }
}

RoutePattern 表示會走到此端點的路由模式

EndpointMiddleware

在web應用程式啟動的時候,會建立一個由RouteEndpoint所組成的端點表
最終endpoint的選擇主要會透過兩個Middleware就決定

  • EndpointRoutingMiddleware
  • EndpointMiddleware

EndpointRoutingMiddleware

這個Middleware主要負責的是

  1. 透過Matcher 物件解析路由參數,並加到當前HttpContextRouteValues
  2. 選出與目前HttpContext最符合的Endpoint,這個endpoint會以Feature的方式存在HttpContext中

Matcher物件頗複雜,預設是DfaMatcher 可以見source code

這個Middleware 主要是透過昨天提到的 app.UseRouting() 所添加到pipeline的

EndpointMiddleware

他的工作很簡單,就是執行被加到HttpContext中的Endpoint
主要透過app.UseEndpoints來添加此Middleware
可以看一下他的source code

稍微節錄一下invoke方法

try
{
    var endpoint = httpContext.GetEndpoint();
    var requestTask = endpoint.RequestDelegate(httpContext);
}

可以看見他去執行了對應的endpoint的方法

註冊Endpoint

比較常見的是app.MapControllers() 他會去掃你的Controller的 Route Attr. 跟 HttpAttr.作為
endpoint的Metadata的一部份

另外也可以透過MapMethods的方式或是Map[HttpMethod] 的方式註冊endpoint

MapMethods

app.MapMethods("/test",
new[] { HttpMethod.Get.ToString() },
async context => await context.Response.WriteAsync("test"));

MapGet

app.MapGet("/books/{isbn}",
    (string isbn) =>
    {
        return isbn switch
        {
            "1234567890" => Results.Ok(new Book("1234567890", "The Hitchhiker's Guide to the Galaxy")),
            "0987654321" => Results.Ok(new Book("0987654321", "The Restaurant at the End of the Universe")),
            _ => Results.NotFound()
        };
    });

上一篇
[Day22] 路由 Routing - 1
下一篇
[Day24] 驗證 - Authencation
系列文
擁抱 .Net Core30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言